#include "apue.h"
#include <sys/un.h>
#include <sys/socket.h>
#include <errno.h>
#define QLEN 10

/**
 * Create a server endpoint of a connection.
 * Return fd if all ok, <0 on error
 */
int serv_listen(const char *name) {
    int fd, len, err, rval;   
    struct sockaddr_un un;
    // 后面使用 strcpy(会复制最后的\0)，所以这里 name 一定要小于 sun_path
    if (strlen(name) >= sizeof(un.sun_path)) {
        errno= ENAMETOOLONG;
        return -1;
    }
    if ((fd= socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
        return -2;
    }
    unlink(name);   /* should delete in case it already exists, after bind function to use */

    memset(&un, 0, sizeof(un));
    un.sun_family= AF_UNIX;
    strcpy(un.sun_path, name);
    len= offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);
    if (bind(fd, (struct sockaddr *)&un, len) < 0) {
        rval= -3; 
        goto errout;
    }
    if (listen(fd, QLEN) < 0) {
        rval= -4;
        goto errout;
    }
    return fd;
errout:
    err= errno;
    close(fd);
    errno= err;
    return rval;
}
